// 消息处理相关功能
import type { Message } from './chat-types';
import { API_BASE_URL } from '@/config/env';
import { isTauri, storageGet } from '../services/secure-storage';
import { showNotification, playNotificationSound } from '../utils/notification';

// 记录上次播放通知音效的时间，用于防抖（避免频繁播放）
let lastSoundPlayTime = 0;
const SOUND_DEBOUNCE_INTERVAL = 10 * 1000; // 10秒内只响一次

/**
 * 检查消息是否已存在（基于 message_id）
 */
export function checkMessageExistsByMessageId(
  messages: Message[],
  incomingMessageId: string
): boolean {
  return messages.some(msg => {
    const msgId = String(msg.message_id);
    return msgId === incomingMessageId || msgId.toLowerCase() === incomingMessageId.toLowerCase();
  });
}

/**
 * 检查消息是否重复（基于内容和时间戳）
 */
export function checkMessageDuplicate(
  messages: Message[],
  message: any,
  incomingMessageId: string,
  incomingTimestamp: number,
  incomingContent: string,
  incomingFileUrl: string,
  incomingChatType: number | undefined,
  incomingFromId: string,
  incomingToId: string,
  isFromCurrentUser: boolean
): { isDuplicate: boolean; duplicateIndex?: number } {
  const now = Date.now();
  const isRecentMessage = Math.abs(now - incomingTimestamp) < 10000; // 10秒内的消息

  if (!isRecentMessage) {
    return { isDuplicate: false };
  }

  const duplicateIndex = messages.findIndex(msg => {
    const msgContent = String(msg.message || '');
    const msgFileUrl = msg.file_url || '';
    const msgTimestamp = msg.timestamp_ms || msg.timestamp || 0;
    const msgFromId = String(msg.from_user_id || '');
    const msgToId = String(msg.to_user_id || '');
    const msgChatType = (msg as any).chat_type;

    const msgIsRecent = Math.abs(now - msgTimestamp) < 10000;
    if (!msgIsRecent) {
      return false;
    }

    // 对于自己发送的消息，只检查自己发送的消息
    if (isFromCurrentUser && msg.isReceived) {
      return false;
    }
    // 对于接收到的消息，只检查接收到的消息
    if (!isFromCurrentUser && !msg.isReceived) {
      return false;
    }

    // 提取消息中可能的图片 URL
    let msgExtractedFileUrl = msgFileUrl;
    if (!msgExtractedFileUrl && msgContent) {
      if (msgContent.startsWith('data:image/')) {
        msgExtractedFileUrl = msgContent;
      } else if (msgContent.startsWith('/api/upload/') || msgContent.match(/^https?:\/\/[^\s]+\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?[^\s]*)?/i)) {
        if (msgContent.startsWith('/api/upload/')) {
          msgExtractedFileUrl = `${API_BASE_URL}${msgContent}`;
        } else {
          const match = msgContent.match(/^https?:\/\/[^\s]+\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?[^\s]*)?/i);
          if (match) {
            msgExtractedFileUrl = match[0];
          }
        }
      }
    }

    // 提取 incoming 消息的图片 URL
    let extractedFileUrl = incomingFileUrl;
    if (!extractedFileUrl && incomingContent) {
      if (incomingContent.startsWith('data:image/')) {
        extractedFileUrl = incomingContent;
      } else if (incomingContent.startsWith('/api/upload/') || incomingContent.match(/^https?:\/\/[^\s]+\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?[^\s]*)?/i)) {
        if (incomingContent.startsWith('/api/upload/')) {
          extractedFileUrl = `${API_BASE_URL}${incomingContent}`;
        } else {
          const match = incomingContent.match(/^https?:\/\/[^\s]+\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?[^\s]*)?/i);
          if (match) {
            extractedFileUrl = match[0];
          }
        }
      }
    }

    // 时间戳在10秒内
    const timeDiff = Math.abs(incomingTimestamp - msgTimestamp);
    if (timeDiff > 10000) {
      return false;
    }

    // 检查 chat_type 是否匹配
    if (msgChatType !== undefined && incomingChatType !== undefined && msgChatType !== incomingChatType) {
      return false;
    }

    // 比较文件 URL
    const fileUrlMatch = (extractedFileUrl && msgExtractedFileUrl && extractedFileUrl === msgExtractedFileUrl) ||
                         (!extractedFileUrl && !msgExtractedFileUrl) ||
                         (extractedFileUrl && msgExtractedFileUrl && (
                           extractedFileUrl.toLowerCase().includes(msgExtractedFileUrl.toLowerCase()) ||
                           msgExtractedFileUrl.toLowerCase().includes(extractedFileUrl.toLowerCase())
                         ));

    // 比较文本内容
    const contentMatch = fileUrlMatch && (
      (msgContent.trim() === incomingContent.trim()) ||
      (extractedFileUrl && msgExtractedFileUrl && fileUrlMatch && 
       (!msgContent || !incomingContent || msgContent.trim() === incomingContent.trim()))
    );

    // 用户匹配
    let userMatch = false;
    
    // 如果 incomingFromId 或 incomingToId 为空，不能判断为重复（可能是消息格式问题）
    if (!incomingFromId || !incomingToId) {
      return false;
    }
    
    if (msgChatType === 2 && incomingChatType === 2) {
      // 群聊消息
      const normalizeGroupId = (id: string) => String(id || '').replace(/^group_/i, '');
      const msgToIdNormalized = normalizeGroupId(msgToId);
      const incomingToIdNormalized = normalizeGroupId(incomingToId);
      userMatch = msgFromId === incomingFromId && msgToIdNormalized === incomingToIdNormalized;
    } else if ((msgChatType === 1 || msgChatType === undefined) && 
               (incomingChatType === 1 || incomingChatType === undefined)) {
      // 单聊消息
      userMatch = msgFromId === incomingFromId && msgToId === incomingToId;
    }

    return contentMatch && userMatch;
  });

  return {
    isDuplicate: duplicateIndex >= 0,
    duplicateIndex: duplicateIndex >= 0 ? duplicateIndex : undefined
  };
}

/**
 * 处理消息内容（提取文件URL等）
 */
export function processMessageContent(
  message: any
): {
  messageContent: string;
  fileUrl?: string;
  fileName?: string;
  fileType?: string;
} {
  let fileUrl = message.file_url;
  let fileName = message.file_name;
  let fileType = message.file_type;
  let messageContent = String(message.message || '');
  const messageContentType = (message as any).message_content_type;

  // 如果消息类型是图片
  if (messageContentType === 2) {
    if (messageContent.startsWith('data:image/')) {
      fileUrl = messageContent;
      if ((message as any).extra) {
        try {
          const extra = JSON.parse((message as any).extra);
          fileName = extra.file_name || fileName;
          fileType = extra.file_type || fileType;
        } catch (e) {
          console.warn('解析 extra 字段失败:', e);
        }
      }
      if (!fileType && messageContent.includes('data:')) {
        const match = messageContent.match(/data:([^;]+)/);
        if (match) {
          fileType = match[1];
        }
      }
      messageContent = '';
    } else if (messageContent.startsWith('/api/upload/') || messageContent.startsWith('http')) {
      if (messageContent.startsWith('/api/upload/')) {
        fileUrl = `${API_BASE_URL}${messageContent}`;
      } else {
        fileUrl = messageContent;
      }
      if ((message as any).extra) {
        try {
          const extra = JSON.parse((message as any).extra);
          // 优先使用 extra 中的 file_name（这是原始文件名）
          fileName = extra.file_name || fileName;
          fileType = extra.file_type || fileType;
          if (extra.file_url) {
            fileUrl = extra.file_url;
            messageContent = String(message.message || '');
          } else {
            if (!messageContent.trim() || messageContent === fileUrl) {
              messageContent = '';
            }
          }
        } catch (e) {
          console.warn('解析 extra 字段失败:', e);
          if (!messageContent.trim() || messageContent === fileUrl) {
            messageContent = '';
          }
        }
      } else {
        if (!messageContent.trim() || messageContent === fileUrl) {
          messageContent = '';
        }
      }
    }
  } else if (messageContentType === 3) {
    // 文件消息：从 message_body 中提取文件 URL（优先）
    // 如果 message_body 是 URL，使用它；否则使用 file_url 字段
    if (messageContent.startsWith('/api/upload/') || messageContent.startsWith('http://') || messageContent.startsWith('https://')) {
      if (messageContent.startsWith('/api/upload/')) {
        fileUrl = `${API_BASE_URL}${messageContent}`;
      } else {
        fileUrl = messageContent;
      }
      // 从 extra 中提取原始文件名
      if ((message as any).extra) {
        try {
          const extra = JSON.parse((message as any).extra);
          fileName = extra.file_name || fileName;
          fileType = extra.file_type || fileType;
        } catch (e) {
          console.warn('解析 extra 字段失败:', e);
        }
      }
      messageContent = ''; // 文件消息不显示 URL 文本
    } else if (fileUrl) {
      // 如果 message_body 不是 URL，但 file_url 字段存在，使用它
      // 从 extra 中提取原始文件名
      if ((message as any).extra) {
        try {
          const extra = JSON.parse((message as any).extra);
          fileName = extra.file_name || fileName;
          fileType = extra.file_type || fileType;
        } catch (e) {
          console.warn('解析 extra 字段失败:', e);
        }
      }
      messageContent = '';
    }
  } else if (fileUrl) {
    messageContent = '';
  }

  return {
    messageContent,
    fileUrl,
    fileName,
    fileType
  };
}

/**
 * 判断是否是当前用户发送的消息
 */
export async function checkIsFromCurrentUser(
  messageFromUserId: string,
  currentUserId: string | null
): Promise<boolean> {
  if (!currentUserId || !messageFromUserId) {
    return false;
  }

  if (messageFromUserId === currentUserId) {
    return true;
  }

  try {
    const userStr = isTauri()
      ? (await storageGet('user')) || '{}'
      : localStorage.getItem('user') || '{}';
    const user = JSON.parse(userStr);
    const currentOpenId = isTauri()
      ? await storageGet('openId')
      : localStorage.getItem('openId');

    return messageFromUserId === (user.open_id || '') ||
           messageFromUserId === (currentOpenId || '') ||
           messageFromUserId === (user.name || '');
  } catch (e) {
    return false;
  }
}

/**
 * 检查是否被@提及（仅群组消息）
 */
export async function checkIsMentioned(
  message: Message,
  isReceived: boolean
): Promise<boolean> {
  if (!isReceived || message.chat_type !== 2 || !message.message) {
    return false;
  }

  try {
    const currentUserOpenId = isTauri()
      ? await storageGet('openId')
      : localStorage.getItem('openId');

    if (!currentUserOpenId) {
      return false;
    }

    let currentUserName: string | null = null;
    try {
      const { getUser } = await import('../services/message');
      const userInfo = await getUser(currentUserOpenId);
      currentUserName = userInfo?.name || null;
    } catch (e) {
      const userStr = localStorage.getItem('user');
      if (userStr) {
        try {
          const user = JSON.parse(userStr);
          currentUserName = user?.name || null;
        } catch (e2) {
          // 解析失败，忽略
        }
      }
    }

    if (currentUserName) {
      const mentionPattern = new RegExp(`@${currentUserName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}(?:\\s|$)`, 'i');
      return mentionPattern.test(message.message);
    }
  } catch (error) {
    console.warn('检查@提及失败:', error);
  }

  return false;
}

/**
 * 触发新消息通知
 */
export async function triggerNewMessageNotification(
  message: Message,
  isMentioned: boolean,
  isCurrentChat: boolean
): Promise<void> {
  if (!message.isReceived) {
    return;
  }

  if (isCurrentChat && !isMentioned) {
    return;
  }

  // 检查消息时间戳，判断是否是离线消息
  const messageTimestamp = message.timestamp_ms || message.timestamp || 0;
  const now = Date.now();
  const messageAge = now - messageTimestamp;
  const MAX_NOTIFICATION_AGE = 2 * 60 * 1000; // 2分钟（实时消息的最大年龄）
  
  // 检查是否是离线消息（刚刚加载的）
  // 如果消息是在WebSocket连接后短时间内加载的，认为是离线消息
  // 我们通过检查消息是否在最近5秒内被处理来判断（这是一个启发式方法）
  // 实际上，离线消息通常是在连接后立即加载的，所以我们可以放宽时间限制
  const OFFLINE_MESSAGE_THRESHOLD = 24 * 60 * 60 * 1000; // 24小时内的离线消息都允许通知
  
  // 对于离线消息（超过2分钟但不超过24小时），允许通知
  // 这样可以确保用户上线时能收到离线消息的通知
  const isOfflineMessage = messageAge > MAX_NOTIFICATION_AGE && messageAge < OFFLINE_MESSAGE_THRESHOLD;
  
  // 对于实时消息（2分钟内），直接允许通知
  // 对于离线消息（2分钟到24小时），也允许通知（用户刚刚上线，需要知道有未读消息）
  // 对于超过24小时的历史消息，不触发通知（避免打扰用户）
  if (messageAge > OFFLINE_MESSAGE_THRESHOLD) {
    console.log('跳过历史消息通知（超过24小时）:', {
      message_id: message.message_id,
      messageAge: `${Math.round(messageAge / (60 * 60 * 1000))}小时前`,
      isMentioned,
    });
    return;
  }
  
  // 如果是离线消息，记录日志
  if (isOfflineMessage) {
    console.log('📥 离线消息通知（允许）:', {
      message_id: message.message_id,
      messageAge: `${Math.round(messageAge / (60 * 1000))}分钟前`,
      chat_type: message.chat_type,
      isMentioned,
    });
  }

  setTimeout(async () => {
    try {
      const notificationSettings = localStorage.getItem('notificationSettings');
      const settings = notificationSettings ? JSON.parse(notificationSettings) : {
        enableDesktopNotification: true,
        enableMessageSound: true,
      };

      const shouldShowNotification = message.chat_type === 2
        ? (settings.enableGroupNotification !== false && settings.enableDesktopNotification !== false)
        : (settings.enableDesktopNotification !== false);

      const shouldPlaySound = settings.enableMessageSound !== false;
      const isWindowFocused = document.hasFocus();
      const shouldNotifyNow = shouldShowNotification && (!isWindowFocused || isMentioned);

      if (shouldNotifyNow) {
        let senderName = '未知用户';
        if (message.chat_type === 2) {
          senderName = `群组 ${String(message.to_user_id || '').substring(0, 10)}`;
        } else {
          senderName = String(message.from_user_id || '').substring(0, 10);
        }

        const messagePreview = message.message?.substring(0, 50) ||
                              (message.file_url ? '[图片]' : '[文件]');

        if (isMentioned) {
          await showNotification(`🔔 ${senderName} @了你`, {
            body: messagePreview,
            icon: '/logo.png',
            badge: '/logo.png',
            tag: `violet-im-mention-${message.from_user_id}-${Date.now()}`,
            requireInteraction: true,
          });
        } else {
          await showNotification(`${senderName} 发来新消息`, {
            body: messagePreview,
            icon: '/logo.png',
            badge: '/logo.png',
            tag: `violet-im-${message.from_user_id}-${Date.now()}`,
          });
        }
      }

      if (shouldPlaySound && (!isWindowFocused || isMentioned)) {
        // 防抖：检查距离上次播放音效的时间，避免频繁播放
        const currentTime = Date.now();
        const timeSinceLastSound = currentTime - lastSoundPlayTime;
        const shouldPlay = timeSinceLastSound >= SOUND_DEBOUNCE_INTERVAL || isMentioned;
        
        if (shouldPlay) {
          if (isMentioned) {
            // @提及时播放两次（间隔300ms）
            playNotificationSound();
            setTimeout(() => {
              playNotificationSound();
            }, 300);
            lastSoundPlayTime = currentTime;
          } else {
            // 普通消息只播放一次
            playNotificationSound();
            lastSoundPlayTime = currentTime;
          }
        } else {
          console.log('跳过音效播放（防抖）:', {
            timeSinceLastSound: `${Math.round(timeSinceLastSound / 1000)}秒前`,
            debounceInterval: `${SOUND_DEBOUNCE_INTERVAL / 1000}秒`,
          });
        }
      }
    } catch (error) {
      console.warn('触发新消息通知失败:', error);
    }
  }, 100);
}

